home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 361_02 / vu.c < prev   
Text File  |  1991-09-18  |  16KB  |  466 lines

  1.  
  2.  
  3. /* VU --> A File Viewer ala MORE w/ Search & Multi-File/Pipe Lists
  4.  *
  5.  * J.Ekwall 13 March, 1990
  6.  *
  7.  * Copyrighted to the Public Domain.  Unlimited Distribution Authorized.
  8.  *
  9.  * User Assumes All Risks/Liabilities.
  10.  *
  11.  */
  12.  
  13. #include <ctype.h>
  14. #include <dos.h>
  15. #include <gadgets.h>
  16. #include <io.h>
  17. #include <keys.h>
  18. #include <setjmp.h>
  19. #include <stdio.h>
  20. #include <stdek.h>
  21. #include <string.h>
  22.  
  23. char *Documentation[] = {
  24.     "",
  25.     "Usage:",
  26.     "       VU [options][drive:][path]filename [, ...] --> View Text Files.",
  27.     "     | VU [options] ---> View a Text Stream ala MORE.",
  28.     "",
  29.     "Options:",
  30.     "       /A -------------> Query for Initial Search.",
  31.     "       /B -------------> Build/ReBuild Select List.",
  32.     "       /C0xhhhhhh -----> Specify Colors.   [D:/C0x1F301E]",
  33.     "       /F \"FindMe\" ----> Jump to Text Match.",
  34.     "       /K -------------> Pop w/ Select List.",
  35.     "       /R -------------> Respect RamPage UnderLines.",
  36.     "       /S -------------> CGA Snow Protection.",
  37.     "",
  38.     "  Named Pipes are Legal.  Pipes are NOT Errased by Viewing.",
  39.     "",
  40.     "Last Updated: 18 September 91/EK",
  41.     "",
  42.     NULL};
  43.  
  44. char *Pop_Help[] = {
  45.     "  <ESC> ---------> Exit & View Next File <If Any>.",
  46.     " Alt-X ----------> Exit. (Don't View Next File).",
  47.     "  <Enter> -------> Pop Item Select List.  <If Any>",
  48.     " ^<Enter> -------> Build/ReBuild a Select List.",
  49.     "   F2 -----------> Find a Text Phrase.",
  50.     "Shift-F2 --------> Find a Text Phrase.  Ignore Case.",
  51.     "   F3 -----------> \"Fuzzy Logic\" Word Finder.",
  52.     "Shift-F3 --------> \"Fuzzy Logic\" Word Finder. Ignore Case.",
  53.     "   F4 -----------> Repeat Search.",
  54.     "   F5 -----------> Strip Hi-Bit Toggle.        [D:don't]",
  55.     "   F6 -----------> Respect RamPage UnderLines. [D:don't]",
  56.     "   F8 -----------> Set F3 \"Fuzz\" Level [D: 5]",
  57.     "   F9 -----------> Select Another File to View",
  58.     "   F10 ----------> Set/Report Color Settings.",
  59.     "",
  60.     "  <Home> / <Page Up>   / <Up Arrow> ----> Roll Upwards.",
  61.     "  <End>  / <Page Down> / <Down Arrow> --> Roll Downward.",
  62.     "  <Right/Left Arrow> --> Shift Text 10 Spaces.",
  63.     "",
  64.     "  Any Other Key -> Roll Down 11 Lines (Half a Screen).",
  65.     NULL};
  66.  
  67.  
  68. char *Pop_Help2[] = {
  69.     "   \"Fuzzy Find\" use the Levenstein Distance Algorithm to",
  70.     "compute a \"FuzzFactor\" (how well what you got matches",
  71.     "what you wanted):",
  72.     "",
  73.     "        Wanted       Have     FuzzFactor",
  74.     "        ──────       ────     ──────────",
  75.     "        FooBar  -->  FooBar ----> 0",
  76.     "        FooBar  -->  fooBar ----> 1",
  77.     "        FooBar  -->  FooxBar ---> 1",
  78.     "        Foo     -->  FooBar ----> 3",
  79.     "        Bar     -->  FooBar ----> 3",
  80.     "        FooBar  -->  FooBat ----> 3",
  81.     "        FooBar  -->  FooBa -----> 7",
  82.     "        FooBar  -->  FoBar -----> 9",
  83.     "        FooBar  -->  Foo -------> 20",
  84.     "",
  85.     "   The Value You Set Determines What will be a \"Match\".",
  86.     NULL};
  87.  
  88. /* Declare Constants */
  89. #define LINESIZE    513
  90.  
  91. /* Declare Globale */
  92. BYTE BarColor = 0x30, NmlColor = 0x1F, HiLite = 0x1E;
  93. int CrashStop = FALSE, WordStar = FALSE, InitAsk = FALSE, InitLst = FALSE;
  94. int Offset = 0, ReBuild = FALSE, Fuzz = 5, RamPage = FALSE, Cleanup = FALSE;
  95. BYTE Find[81], Line[LINESIZE], Name[81], Text[LINESIZE], LastFind[81];
  96. FILE *fp = stdin;
  97.  
  98. /* Declare Local ProtoTypes */
  99. int  AtoHexColors(char **ptr);
  100. int  FindLine(int Start, int CaseLess);
  101. int  FuzzyFind(char *Have, char *Want);
  102. void GrabStdin(void);
  103. int  ItemList(void);
  104. void PaintCRT(int TopLine);
  105. void Show(int CaseLess);
  106. void Usage(void);
  107. void UserSetsColors(void);
  108.  
  109. main (int argc, char *argv[])
  110. {
  111.     int i, xx, yy, Flag = FALSE;
  112.     char *tp1, FootPrint[4000];
  113.  
  114.  /* Set Option Flags */
  115.     *Find = *LastFind = NULL;
  116.     while (*argv[1] IS SLASH) {
  117.        for (tp1 = argv[1] + 1; *tp1 != NULL; ) {
  118.       switch (toupper(*tp1++)) {
  119.       case 'A': InitAsk++; break;
  120.       case 'B': ReBuild++; break;
  121.           case 'C':             /* Colors */
  122.          if (!AtoHexColors(&tp1)) Usage(); break;
  123.           case 'F':
  124.              if (argc IS 2) Usage();
  125.              for (i = 1, --argc; i < argc + 1; i++) argv[i] = argv[i+1];
  126.              strcpy(Find,argv[1]); strupr(Find); Flag = TRUE;
  127.              break;
  128.       case 'K': InitLst++; break;
  129.       case 'S': CgaSnowFence(); break;
  130.           default:
  131.              fprintf(stderr,"\nInvalid Option [/%c].\n\n",*tp1);
  132.              Usage();
  133.           }
  134.        }
  135.  
  136.     /* SHIFT */
  137.        for (i = 1, --argc; i < argc + 1; i++) argv[i] = argv[i+1];
  138.     }
  139.  
  140.  /* Save FootPrint Area */
  141.     Getxy(&xx, &yy); SaveBox(1, 1, 80, 25, FootPrint); HideCursor();
  142.  
  143.  /* Determine Ops Mode */
  144.     if (argc IS 1)  {                    /* Barefoot Mode */
  145.        if (INFLOW_EXISTS) GrabStdin();
  146.        if (FileExists("\\STD OUT")) strcpy(Name,"\\STD OUT");
  147.        else if (FileExists("\\STD IN"))  strcpy(Name,"\\STD IN");
  148.        else Usage();
  149.        Show(Flag); argc--;
  150.     }
  151.  
  152.  /* Show the Specified Files */
  153.     for (i = 1; i < argc; i++) {
  154.        if (*argv[i] IS '$') {
  155.           strcpy(Name,"\\STD "); strcat(Name,++argv[i]);
  156.        } else strcpy(Name,argv[i]);
  157.        if (FileExists(Name)) Show(Flag);
  158.        Flag = FALSE; GetLineN(NULL, 0); if (CrashStop) break;
  159.     }
  160.  
  161.  /* Restore FootPrint & Split */
  162.     RestoreBox(1, 1, 80, 25, FootPrint); Gotoxy(xx, yy); ShowCursor(0);
  163.     if (Cleanup) unlink("\\STD IN"); exit(0);
  164. }
  165.  
  166. int AtoHexColors(char **ptr)
  167. {
  168.     int c, i = 0;
  169.     unsigned int n = 0;
  170.  
  171.     if (strncmp(*ptr, "0x", 2) && strncmp(*ptr, "0X", 2)) return FALSE;
  172.     for (*ptr += 2; isxdigit(c = toupper(**ptr)) && i++ < 6; *ptr += 1) {
  173.     n = (isdigit(c)) ? 16 * n + c - 48 : 16 * n + c - 55;
  174.     if (i IS 2) { NmlColor = n; n = 0; }
  175.     if (i IS 4) { BarColor = n; n = 0; }
  176.     if (i IS 6) HiLite = n;
  177.     }
  178.     return (i >= 6);
  179. }
  180.  
  181. int FindLine(int Start, int CaseLess)
  182. {
  183.     int i, Dits = 18;
  184.     char *tp1, DitLine[81];
  185.  
  186.     if (!*Find) return(Start); strcpy(DitLine, "---<Scanning>--- ");
  187.     strcpy(LastFind, Find);
  188.     for (i = Start; GetLineN(Line, (++i) + 1); ) {
  189.        if (WordStar) for (tp1 = Line; *tp1 != NULL; ) *tp1++ &= 127;
  190.        if (CaseLess % 2) strupr(Line);
  191.        if (CaseLess < 2) { if(strstr(Line, Find) != NULL) return(i); }
  192.        else for (tp1 = strtok(Line, " \t\n"); *tp1;
  193.       tp1 = strtok(NULL, " \t\n")) if (FuzzyFind(tp1, Find) < Fuzz)
  194.              return(i);
  195.        if (i % 23) continue;
  196.        if (++Dits IS 78) {
  197.           strcpy(DitLine,"."); Dits = 1;
  198.        } else strcat(DitLine, ".");
  199.        DwriteEnd(1, 25, BarColor, DitLine, 80);
  200.        if (Kbq_poll() IS SPACE) break;
  201.     }
  202.     putchar(BEL); return(Start);
  203. }
  204.  
  205. int FuzzyFind(char *Have, char *Want)
  206. {
  207.     int i, j, Delta, Prev, Distance[21];
  208.     char Text[21], String[21], *tp1, *tp2;
  209.  
  210.     strncpy(Text, Want, 20); strncpy(String, Have, 20);
  211.     Text[21] = String[21] = NULL; if (!*Want) return 0;
  212.     if (!*Have) return 5 * strlen(Want);
  213.     for (i = 0; i < 21; i++) Distance[i] = i;
  214.     tp1 = Text;
  215.     do {
  216.        Prev = Distance[0] + 5; tp2 = String; i = 0;
  217.        do {
  218.           Delta = Prev + 1;
  219.           if (*tp1 == *tp2) j = 0;
  220.       else if (toupper(*tp1) == toupper(*tp2)) j = 1;
  221.           else j = 3;
  222.       if ((j += Distance[i]) < Delta) Delta = j; Distance[i] = Prev;
  223.       if ((j = Distance[++i] + 5) < Delta) Delta = j; Prev = Delta;
  224.        } while (*tp2++);
  225.        Distance[strlen(String)] = Delta;
  226.     } while (*tp1++);
  227.     if ((j = strlen(Text) - strlen(String)) > 0) Delta += 4 * j;
  228.     return --Delta;
  229. }
  230.  
  231. void GrabStdin(void)
  232. {
  233.     int c;
  234.  
  235.     if ((fp = fopen("\\STD IN", "w")) IS NULL) Usage();
  236.     while((c = getchar()) != EOF) fputc(c, fp);
  237.     fclose(fp); Cleanup++;
  238. }
  239.  
  240. int ItemList(void)
  241. {
  242.  /* Find/Read .LST File, Present List(s) & Post User Selection */
  243.     int i, Flag, TopItem, NxtLine, X, Y, xx, yy;
  244.     char ListName[81], *tp1;
  245.  
  246.  /* Find .LST File */
  247.     strupr(Name); if (strstr(Name, ".TXT") IS NULL) return FALSE;
  248.     NewExt(Name, ListName, "LST");
  249.